package com.mybatis.jpa.sqlbuilder;

import com.mybatis.jpa.sqlbuilder.insert.ByteCodeFactory;
import com.mybatis.jpa.sqlbuilder.insert.SqlWriter;
import com.mybatis.jpa.utils.MappedStatementUtils;
import com.mybatis.jpa.utils.ObjectFacade;
import com.mybatis.jpa.utils.StopWatchExt;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * List<Object> 集合转换sql，List<Map>不支持转换（InsertMapSqlBuilder实现List<Map>转换sql）
 * @author K
 *
 */
public class InsertSqlBuilder extends SqlBuilder {

	private static final Logger logger = LoggerFactory.getLogger( InsertSqlBuilder.class);
	@Override
	public String buildSql(MetaObject metaStatementHandler) throws Exception {
		StopWatchExt stopWatchExt = new StopWatchExt();
		MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");
		String sqlPlaceholderAlias = "list";
		List<String> values = new ArrayList<>();
		Map<String, Object> paramMap = (Map<String, Object>) metaStatementHandler.getValue("delegate.boundSql.parameterObject");
		//获取传入参数
		List<Object> list = super.getInsertParamList(paramMap);

		Class entityClass = MappedStatementUtils.getEntityClass(mappedStatement);
		ObjectFacade objectFacade = new ObjectFacade(entityClass);
		String tableName = objectFacade.getTableName();
		List<String> columns = objectFacade.getColumnNames();
		this.filter(paramMap, columns);
		
		SqlWriter sqlWriter  = ByteCodeFactory.createSqlWriter(objectFacade, getExcludeColumn(paramMap).toString(), sqlPlaceholderAlias);
		
		StringBuilder tableSql = new StringBuilder();  
		StringBuilder valueSql = new StringBuilder(); 
	    tableSql.append("insert into ").append(tableName).append("(").append(StringUtils.join(columns, ",")).append(") values ");
	    
	    for (int i = 0; i  < list.size(); i++) {
	    	if (valueSql.length() > 0) {
	    		valueSql.append(",");
			}

	    	Object obj = list.get(i);
	    	valueSql.append("(");
			values.addAll(sqlWriter.writer(obj, i));
		    valueSql.append(StringUtils.join(values, ","));
		    valueSql.append(")");
		    values.clear();
	    }

	    String sql = tableSql.append(valueSql).toString();
		logger.info("生成insert sql耗时：{}", stopWatchExt.getTimeWithReset(true));
		return sql;
	}
}
